import { inject } from "../inject";
import { IEventMap } from "./base/IEventMap";
import { EventMap } from "./impl/EventMap";
import { MediatorBase } from "./impl/MediatorBase";
import { MediatorMap } from "./impl/MediatorMap";
import { ViewMap } from "./impl/ViewMap";

export class Mediator extends MediatorBase {

    @inject('core.MediatorMap')
    public mediatorMap: MediatorMap;

    @inject('core.ViewMap')
    public viewMap: ViewMap;

    protected _eventMap: EventMap = null;

    public preRegister(): void {
        let listEventTypes = this.listEventTypes();
        if (listEventTypes.length > 0) {
            for (let i = 0; i < listEventTypes.length; i++) {
                const event = listEventTypes[i];
                this.addViewListener(event, (...args: any[]) => {
                    this.handleNotification(event, ...args);
                });
            }
        }

        super.preRegister();
    }

    public preRemove(): void {
        if (this._eventMap) {
            this._eventMap.unmapListeners();
        }

        super.preRemove();
    }

    protected get eventMap(): IEventMap {
        if (!this._eventMap) {
            this._eventMap = new EventMap(this.dispatcher);
        }

        return this._eventMap;
    }

    protected addViewListener(event: string, listener: Function, priority: number = 0) {
        this.eventMap.mapListener(this.dispatcher, event, listener, this, priority);
    }

    protected removeViewListener(event: string, listener: Function) {
        this.eventMap.unmapListener(this.dispatcher, event, listener, this);
    }

    protected addContextListener(event: string, listener: Function, priority: number = 0) {
        this.eventMap.mapListener(this.dispatcher, event, listener, this, priority);
    }

    protected removeContextListener(event: string, listener: Function) {
        this.eventMap.unmapListener(this.dispatcher, event, listener, this);
    }

    listEventTypes(): string[] {
        return new Array<string>();
    }

    handleNotification(event: string, ...args: any[]): void {

    }
}